
public class Test {
    public static void main(String[] args) throws Exception {
        Coffee c = new SimpleCoffee();
        c = new MilkDecorator(c); // 加奶
        c = new SugarDecorator(c); // 再加糖
        System.out.println(c.desc() + " ￥" + c.cost());
    }

}

// 装饰器模式 = “不继承、不修改原类，动态地给对象加功能”
// 核心：
// 先让“装饰器”实现/继承跟原类一样的接口/父类
// 在装饰器里持有原对象
// 先调原功能，再附加新功能，可套娃任意层
// 公共接口
interface Coffee {
    double cost();

    String desc();
}

// 原对象
class SimpleCoffee implements Coffee {
    public double cost() {
        return 2;
    }

    public String desc() {
        return "Coffee";
    }
}

// 装饰器基座
abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee; // 持有被装饰对象

    CoffeeDecorator(Coffee c) {
        this.coffee = c;
    }
}

// 具体装饰器（可套娃）
class MilkDecorator extends CoffeeDecorator {
    MilkDecorator(Coffee c) {
        super(c);
    }

    public double cost() {
        return coffee.cost() + 0.5;
    }

    public String desc() {
        return coffee.desc() + ", milk";
    }
}

class SugarDecorator extends CoffeeDecorator {
    SugarDecorator(Coffee c) {
        super(c);
    }

    public double cost() {
        return coffee.cost() + 0.2;
    }

    public String desc() {
        return coffee.desc() + ", sugar";
    }
}